/**    
 * 文件名：Ex6ContentDetectionGrayscale.java    
 *    
 * 版本信息：    
 * 日期：2014年3月10日    
 * xyj 足下 xyj 2014     
 * 版权所有    
 *    
 */
package opencvtest.chapter04;

import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_32F;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCalcBackProject;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvNormalizeHist;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvReleaseHist;
import static opencvtest.OpenCVUtils.drawOnImage;
import static opencvtest.OpenCVUtils.loadOrExit;
import static opencvtest.OpenCVUtils.scaleTo01;
import static opencvtest.OpenCVUtils.show;
import static opencvtest.OpenCVUtils.toIplImage32F;
import static opencvtest.OpenCVUtils.toIplROI;

import java.awt.Color;
import java.awt.Rectangle;
import java.io.File;

import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_imgproc.CvHistogram;

/**
 * Uses histogram of a region in an gray scale image to create 'template', looks
 * through the whole image to detect pixels that are similar to that template.
 * Example for section
 * "Backprojecting a histogram to detect specific image content" in Chapter 4.
 */
public class Ex6ContentDetectionGrayscale {

    public static void main(String[] args) throws Exception {

        // Load image as a gray scale
        IplImage src = loadOrExit(new File("data/waves.jpg"), CV_LOAD_IMAGE_GRAYSCALE);

        // Display image with marked ROI
        Rectangle rect = new Rectangle(360, 44, 40, 50);
        show(drawOnImage(src, rect, Color.RED), "Input");

        // Define ROI
        src.roi(toIplROI(rect));

        // Compute histogram within the ROI
        CvHistogram h = new Histogram1D().getHistogram(src, null);

        show(new Histogram1D().getHistogram(h), "roi h");

        // Normalize histogram so the sum of all bins is equal to 1.
        cvNormalizeHist(h, 1);

        show(new Histogram1D().getHistogram(h), "normailize h");

        // Remove ROI, we will be using full image for the rest
        src.roi(null);

        // Back projection is done using 32 floating point copy of the input
        // image.
        // The output is also 32 bit floating point
        IplImage dest = IplImage.create(cvGetSize(src), IPL_DEPTH_32F, src.nChannels());
        cvCalcBackProject(new IplImage[] { toIplImage32F(src) }, dest, h);
        cvReleaseHist(h);

        // Show results
        show(scaleTo01(dest), "Backprojection result");

    }
}
